/** cTestEvaluators
 * 
 * Tests both the decision behavior and hand ranking integration
 * 
 * @author lcballa44
 *
 */
/* fully explicit card to integer conversions :
    
2c =  0    2d = 13    2h = 26    2s = 39
3c =  1    3d = 14    3h = 27    3s = 40
4c =  2    4d = 15    4h = 28    4s = 41
5c =  3    5d = 16    5h = 29    5s = 42
6c =  4    6d = 17    6h = 30    6s = 43
7c =  5    7d = 18    7h = 31    7s = 44
8c =  6    8d = 19    8h = 32    8s = 45
9c =  7    9d = 20    9h = 33    9s = 46
Tc =  8    Td = 21    Th = 34    Ts = 47
Jc =  9    Jd = 22    Jh = 35    Js = 48
Qc = 10    Qd = 23    Qh = 36    Qs = 49
Kc = 11    Kd = 24    Kh = 37    Ks = 50
Ac = 12    Ad = 25    Ah = 38    As = 51

*/

public class cTestEvaluators {
	public static void main(String[] args) {
		HandEvaluator handEvaluator = new HandEvaluator();
		cBehaviorModule behaviorModule = new cBehaviorModule();
		Deck testDeck = new Deck(0);
		testDeck.reset();
		
		Hand testHand = new Hand();
		
		// Test a good hand (quad aces with king kicker)
		testHand.addCard(testDeck.getCard(12) );  //Ac
		testHand.addCard(testDeck.getCard(25) );  //Ad
		testHand.addCard(testDeck.getCard(38));  //Ah
		testHand.addCard(testDeck.getCard(51) );  //As
		testHand.addCard(testDeck.getCard(11) );  //Kc
		
		System.out.println("The current hand being tested is " + testHand.toString());
		
		int handRank = handEvaluator.rankHand(testHand);
		System.out.println("    Hand Rank is " + handRank);
		System.out.println("    Hand Rank after normalization is " + handRank/371293);
		System.out.println("    Hand Name is " + HandEvaluator.nameHand(testHand));
		
		double fold = 0;
		double call = 0;
		double raise = 0;
		double check = 0;
		double decision = -1;
		int runs = 10000;
		int round = 1;
		int curBet = 0;
		
		// Quad Aces, Round 1, Current Bet 0
		for(int i = 0; i < runs; i++){
			int rank = (int)handRank/371293;
			decision = behaviorModule.makeDecision(rank, round, curBet);
			if(decision == 0)
				fold++;
			else if(decision == 2)
				call++;
			else if(decision == 3)
				check++;
			else
				raise++;
		}
		System.out.println("    Decision breakdown after " + runs + 
				" trials with during Round " + round + " and current bet of " + curBet );
		System.out.println("    % Folds " + fold/runs*100);
		System.out.println("    % Calls " + call/runs*100);
		System.out.println("    % Checks " + check/runs*100);
		System.out.println("    % Raises " + raise/runs*100);
		System.out.println("");
		
		// Quad Aces, Round 4, Current Bet 100
		round = 4;
		curBet = 100;
		fold = 0;
		call = 0;
		raise = 0;
		check = 0;
		for(int i = 0; i < runs; i++){
			int rank = (int)handRank/371293;
			decision = behaviorModule.makeDecision(rank, round, curBet);
			if(decision == 0)
				fold++;
			else if(decision == 2)
				call++;
			else if(decision == 3)
				check++;
			else
				raise++;
		}
		System.out.println("    Decision breakdown after " + runs + 
				" trials with during Round " + round + " and current bet of " + curBet );
		System.out.println("    % Folds " + fold/runs*100);
		System.out.println("    % Calls " + call/runs*100);
		System.out.println("    % Checks " + check/runs*100);
		System.out.println("    % Raises " + raise/runs*100);
		System.out.println("");
		
	/**  Low Hand **/	
		fold = 0;
		call = 0;
		raise = 0;
		check = 0;
		// Test a good hand (quad aces with king kicker)
		testHand.makeEmpty();
		testHand.addCard(testDeck.getCard(0) );  
		testHand.addCard(testDeck.getCard(15) );  
		testHand.addCard(testDeck.getCard(32));  
		testHand.addCard(testDeck.getCard(5) );  
		testHand.addCard(testDeck.getCard(11) );  
		testHand.addCard(testDeck.getCard(1) );  
		testHand.addCard(testDeck.getCard(33) ); 
		
		System.out.println("The current hand being tested is " + testHand.toString());
		
		handRank = handEvaluator.rankHand(testHand);
		System.out.println("    Hand Rank is " + handRank);
		System.out.println("    Hand Rank after normalization is " + handRank/371293);
		System.out.println("    Hand Name is " + HandEvaluator.nameHand(testHand));
		
// Bad Hand, Round 1, Current Bet 0
		for(int i = 0; i < runs; i++){
			int rank = (int)handRank/371293;
			decision = behaviorModule.makeDecision(rank, round, curBet);
			if(decision == 0)
				fold++;
			else if(decision == 2)
				call++;
			else if(decision == 3)
				check++;
			else
				raise++;
		}
		System.out.println("    Decision breakdown after " + runs + 
				" trials with during Round " + round + " and current bet of " + curBet );
		System.out.println("    % Folds " + fold/runs*100);
		System.out.println("    % Calls " + call/runs*100);
		System.out.println("    % Checks " + check/runs*100);
		System.out.println("    % Raises " + raise/runs*100);
		System.out.println("");
		
		// Bad Hand, Round 4, Current Bet 100
		round = 4;
		curBet = 100;
		fold = 0;
		call = 0;
		raise = 0;
		check = 0;
		for(int i = 0; i < runs; i++){
			int rank = (int)handRank/371293;
			decision = behaviorModule.makeDecision(rank, round, curBet);
			if(decision == 0)
				fold++;
			else if(decision == 2)
				call++;
			else if(decision == 3)
				check++;
			else
				raise++;
		}
		System.out.println("    Decision breakdown after " + runs + 
				" trials with during Round " + round + " and current bet of " + curBet );
		System.out.println("    % Folds " + fold/runs*100);
		System.out.println("    % Calls " + call/runs*100);
		System.out.println("    % Checks " + check/runs*100);
		System.out.println("    % Raises " + raise/runs*100);
		System.out.println("");
		
	/** start testing hole card evaluator **/
		System.out.println("Testing Hole Card Ranker");
		System.out.println("");
		
		testDeck.reset();
		testHand.makeEmpty();
		Card holeCard1 = testDeck.getCard(12);
		Card holeCard2 = testDeck.getCard(25);
		testHand.addCard(holeCard1 );  //Ac
		testHand.addCard(holeCard2 );  //Ad
		
		System.out.println("The current hand being tested is " + testHand.toString());
		handRank = HoleCardRanker.rankPair(holeCard1, holeCard2);
		System.out.println("    Hand Rank is " + handRank);
		System.out.println("    Hand Name is " + HandEvaluator.nameHand(testHand));
		
		round = 1;
		curBet = 0;
		fold = 0;
		call = 0;
		raise = 0;
		check = 0;
		for(int i = 0; i < runs; i++){
			decision = behaviorModule.makeDecision((int)handRank, round, curBet);
			if(decision == 0)
				fold++;
			else if(decision == 2)
				call++;
			else if(decision == 3)
				check++;
			else
				raise++;
		}
		System.out.println("    Decision breakdown after " + runs + 
				" trials with during Round " + round + " and current bet of " + curBet );
		System.out.println("    % Folds " + fold/runs*100);
		System.out.println("    % Calls " + call/runs*100);
		System.out.println("    % Checks " + check/runs*100);
		System.out.println("    % Raises " + raise/runs*100);
		System.out.println("");
		
		
		testDeck.reset();
		testHand.makeEmpty();
		 holeCard1 = testDeck.getCard(0);
		 holeCard2 = testDeck.getCard(18);
		testHand.addCard(holeCard1 );  
		testHand.addCard(holeCard2 );  
		
		System.out.println("The current hand being tested is " + testHand.toString());
		handRank = HoleCardRanker.rankPair(holeCard1, holeCard2);
		System.out.println("    Hand Rank is " + handRank);
		System.out.println("    Hand Name is " + HandEvaluator.nameHand(testHand));
		
		round = 1;
		curBet = 0;
		fold = 0;
		call = 0;
		raise = 0;
		check = 0;
		for(int i = 0; i < runs; i++){
			decision = behaviorModule.makeDecision((int)handRank, round, curBet);
			if(decision == 0)
				fold++;
			else if(decision == 2)
				call++;
			else if(decision == 3)
				check++;
			else
				raise++;
		}
		System.out.println("    Decision breakdown after " + runs + 
				" trials with during Round " + round + " and current bet of " + curBet );
		System.out.println("    % Folds " + fold/runs*100);
		System.out.println("    % Calls " + call/runs*100);
		System.out.println("    % Checks " + check/runs*100);
		System.out.println("    % Raises " + raise/runs*100);
		System.out.println("");
		
		
		
		
		/**  Testing HandEvaluator.name_hand(hand)  */
		
		testHand.makeEmpty();
		testHand.addCard(testDeck.getCard(0) );  
		testHand.addCard(testDeck.getCard(13) );  
		testHand.addCard(testDeck.getCard(32));  
		testHand.addCard(testDeck.getCard(5) );  
		testHand.addCard(testDeck.getCard(11) );  
		testHand.addCard(testDeck.getCard(1) );  
		testHand.addCard(testDeck.getCard(33) ); 
		
		int testRank = HandEvaluator.rankHand(testHand);
		
		System.out.println(""+ testRank + ":" + HandEvaluator.name_hand(testRank));
		System.out.println(""+ 0 + ":" + HandEvaluator.name_hand(0));
		System.out.println(""+ (HandEvaluator.ID_GROUP_SIZE - 100000) + ":" + HandEvaluator.name_hand(HandEvaluator.ID_GROUP_SIZE - 100000));
		System.out.println(""+ (HandEvaluator.ID_GROUP_SIZE - 10) + ":" + HandEvaluator.name_hand(HandEvaluator.ID_GROUP_SIZE - 10));
		
		
	}
}
